home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / bd3.zip / BD3.ADA next >
Text File  |  1989-03-13  |  20KB  |  541 lines

  1. package BANK is
  2. --------------------------------------------------------------------------
  3. --| BEGIN PROLOGUE
  4. --| DESCRIPTION            : BANK defines a bank, the TELLER objects
  5. --|                        : within it, and the procedure PRINT_REPORT
  6. --|                        : (which reports on the status of the BANK).
  7. --|                        :
  8. --|                        : BANK is an abstract state machine, defining
  9. --|                        : a BANK object which contains TELLER objects.
  10. --|                        :
  11. --| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
  12. --|                        : object-oriented design and tasking
  13. --|                        : with Ada
  14. --|                        :
  15. --| LIMITATIONS            : None
  16. --| AUTHOR(S)              : Richard Conn (RLC)
  17. --| CHANGE LOG             : 1/16/89  RLC  Initial Design and Code
  18. --| CHANGE LOG             : 2/25/89  RLC  Final Review Prior to Release
  19. --| REMARKS                : None
  20. --| PORTABILITY ISSUES     : None
  21. --| END PROLOGUE
  22. --------------------------------------------------------------------------
  23.  
  24.     -- TRANSACTION requested of a TELLER
  25.     type TRANSACTION  is (ADD_NEW_CUSTOMER,
  26.                           GET_BALANCE,
  27.                           MAKE_DEPOSIT,
  28.                           MAKE_WITHDRAWAL);
  29.  
  30.     -- Unit of currency
  31.     type DOLLAR       is new FLOAT;
  32.  
  33.     -- Identification of a CUSTOMER
  34.     type CUSTOMER_ID  is new NATURAL range 1 .. NATURAL'LAST;
  35.  
  36.     -- Index of and Number of TELLER objects within the bank
  37.     type TELLER_INDEX is new NATURAL range 1 .. 4;
  38.  
  39.     -- A TELLER_PERSON is an object to which a CUSTOMER may make a REQUEST
  40.     -- The BANK tells the TELLER_PERSON to START_WORK, giving the
  41.     -- TELLER_PERSON its TELLER_NUMBER
  42.     task type TELLER_PERSON is
  43.     entry REQUEST(ID     : in out CUSTOMER_ID;
  44.               KIND   : in TRANSACTION;
  45.               AMOUNT : in out DOLLAR);
  46.     end TELLER_PERSON;
  47.     -- These are the TELLER objects available at the bank
  48.     TELLER : array(TELLER_INDEX) of TELLER_PERSON;
  49.  
  50.     -- PRINT_REPORT gives the transaction log of all the bank
  51.     -- customers
  52.     procedure PRINT_REPORT;
  53.  
  54.     -- STOP_WORK terminates all TELLER tasks
  55.     procedure STOP_WORK;
  56. end BANK;
  57. -- 
  58. with CONSOLE;
  59. package body BANK is
  60. --------------------------------------------------------------------------
  61. --| BEGIN PROLOGUE
  62. --| DESCRIPTION            : Package Body BANK implements the TELLER
  63. --|                        : tasks and the PRINT_REPORT procedure.
  64. --|                        : CUSTOMER data is maintained within the
  65. --|                        : BANK as a linked list.
  66. --|                        :
  67. --| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
  68. --|                        : object-oriented design and tasking
  69. --|                        : with Ada
  70. --|                        :
  71. --| LIMITATIONS            : None
  72. --| AUTHOR(S)              : Richard Conn (RLC)
  73. --| CHANGE LOG             : 1/16/89  RLC  Initial Design and Code
  74. --| CHANGE LOG             : 2/25/89  RLC  Final Review Prior to Release
  75. --| REMARKS                : None
  76. --| PORTABILITY ISSUES     : Uses CONSOLE (TEXT_IO), so is very portable;
  77. --|                        : no known portability problems.
  78. --| END PROLOGUE
  79. --------------------------------------------------------------------------
  80.  
  81.     -- Identifier of next customer
  82.     NEXT_ID                  : CUSTOMER_ID           := CUSTOMER_ID'FIRST;
  83.  
  84.     -- Linked list of customer data
  85.     type CUSTOMER_DATA;
  86.     type CUSTOMER_DATA_POINTER is access CUSTOMER_DATA;
  87.     type CUSTOMER_DATA is record
  88.     ID                  : CUSTOMER_ID;
  89.     BALANCE             : DOLLAR                := 0.0;
  90.     TRANSACTION_COUNT   : NATURAL               := 0;
  91.     ATTEMPTED_OVERDRAWS : NATURAL               := 0;
  92.     NEXT                : CUSTOMER_DATA_POINTER := null;
  93.     end record;
  94.  
  95.     -- Count of number of transactions for each TELLER object
  96.     TELLER_TRANSACTION_COUNT : array(TELLER_INDEX) of NATURAL 
  97.       := (others => 0);
  98.  
  99.     -- Pointers to first and last customer data entries
  100.     FIRST_CUSTOMER           : CUSTOMER_DATA_POINTER := null;
  101.     LAST_CUSTOMER            : CUSTOMER_DATA_POINTER := null;
  102.  
  103. -- 
  104. -- package body BANK
  105.     -- Print a report of the status of the BANK
  106.     procedure PRINT_REPORT is
  107.     CURRENT_CUSTOMER : CUSTOMER_DATA_POINTER;
  108.     begin
  109.  
  110.         -- Check for any customers and issue an error message if none
  111.     if NEXT_ID = CUSTOMER_ID'FIRST then
  112.         CONSOLE.WRITE("The bank doesn't have any customers");
  113.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  114.  
  115.         -- Generate report
  116.     else
  117.  
  118.             -- Customer balance, transaction count, attempted overdraw
  119.             -- count report
  120.         CONSOLE.WRITE("**** BANK STATUS REPORT ****");
  121.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  122.         CONSOLE.WRITE(
  123.               "Customer      Balance  Transactions  Attempted_Overdraws");
  124.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  125.         CURRENT_CUSTOMER := FIRST_CUSTOMER;
  126.         while CURRENT_CUSTOMER /= null loop
  127.         CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.ID), 5);
  128.         CONSOLE.WRITE("     ");
  129.         CONSOLE.WRITE(FLOAT(CURRENT_CUSTOMER.BALANCE), 8, 2);
  130.         CONSOLE.WRITE("      ");
  131.         CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.TRANSACTION_COUNT), 8);
  132.         CONSOLE.WRITE("             ");
  133.         CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.ATTEMPTED_OVERDRAWS),
  134.           8);
  135.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  136.         CURRENT_CUSTOMER := CURRENT_CUSTOMER.NEXT;
  137.         end loop;
  138.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  139.  
  140.             -- Teller transaction count report
  141.         CONSOLE.WRITE("Teller           : ");
  142.         for I in TELLER_INDEX loop
  143.         CONSOLE.WRITE(INTEGER(I), 8);
  144.         end loop;
  145.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  146.         CONSOLE.WRITE("Transaction_Count: ");
  147.         for I in TELLER_INDEX loop
  148.         CONSOLE.WRITE(INTEGER(TELLER_TRANSACTION_COUNT(I)), 8);
  149.         end loop;
  150.         CONSOLE.WRITE(CONSOLE.NEW_LINE);
  151.  
  152.     end if;
  153.     end PRINT_REPORT;
  154.  
  155.     -- Terminate all TELLER tasks
  156.     procedure STOP_WORK is
  157.     begin
  158.     for I in TELLER_INDEX loop
  159.         abort TELLER(I);
  160.     end loop;
  161.     end STOP_WORK;
  162. -- 
  163. -- package body BANK
  164.  
  165.     -- FIND_CUSTOMER is used to find a CUSTOMER_DATA record
  166.     -- based on a CUSTOMER_ID number
  167.     function FIND_CUSTOMER(ID : in CUSTOMER_ID)
  168.                 return CUSTOMER_DATA_POINTER is
  169.     CURRENT_CUSTOMER : CUSTOMER_DATA_POINTER;
  170.     begin
  171.     CURRENT_CUSTOMER := FIRST_CUSTOMER;
  172.     while CURRENT_CUSTOMER /= null loop
  173.         exit when CURRENT_CUSTOMER.ID = ID;
  174.         CURRENT_CUSTOMER := CURRENT_CUSTOMER.NEXT;
  175.     end loop;
  176.     return CURRENT_CUSTOMER;
  177.     end FIND_CUSTOMER;
  178.  
  179.  
  180. -- 
  181. -- package body BANK
  182.  
  183.     task TELLER_ASSIGNER is
  184.     -- This task assigns an ID number to a teller.
  185.     -- TELLER_ASSIGNER is called by the TELLER_PERSON task when the
  186.     -- TELLER_PERSON task first starts up.
  187.     entry GET_TELLER_ID(ID : out TELLER_INDEX);
  188.     end TELLER_ASSIGNER;
  189.  
  190.     task body TELLER_ASSIGNER is
  191.     NEXT_TELLER_ID : TELLER_INDEX := TELLER_INDEX'FIRST;
  192.     begin
  193.     loop
  194.         accept GET_TELLER_ID(ID : out TELLER_INDEX) do
  195.         ID := NEXT_TELLER_ID;
  196.         if NEXT_TELLER_ID /= TELLER_INDEX'LAST then
  197.             NEXT_TELLER_ID := NEXT_TELLER_ID + 1;
  198.         end if;
  199.         end GET_TELLER_ID;
  200.     end loop;
  201.     end TELLER_ASSIGNER;
  202.  
  203. -- 
  204. -- package body BANK
  205.  
  206.     -- Implementation of a TELLER task
  207.     task body TELLER_PERSON is
  208.  
  209.     THIS_CUSTOMER : CUSTOMER_DATA_POINTER;
  210.     MY_NUMBER     : TELLER_INDEX;
  211.  
  212.     begin
  213.  
  214.         -- TELLER gets his ID number
  215.     TELLER_ASSIGNER.GET_TELLER_ID(MY_NUMBER);
  216.  
  217.         -- TELLER loops on REQUESTs from CUSTOMERs
  218.     loop
  219.         accept REQUEST(ID     : in out CUSTOMER_ID;
  220.                KIND   : in TRANSACTION;
  221.                AMOUNT : in out DOLLAR) do
  222.  
  223.                 -- Increment teller's transaction count
  224.         TELLER_TRANSACTION_COUNT(MY_